﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Build.Utilities;
using Microsoft.Build.Tasks;
using Microsoft.Build.Framework;
using ZealandIT.MsBuildTasks.Common;

namespace ZealandIT.MsBuildTasks
{
    /// <summary>
    /// Extension of standard MSBuild Exec task, but runs under impersonated user context.
    /// </summary>
    public class RunAs : Exec
    {
        private string _username;
        private string _password;

        /// <summary>
        /// Username of user to be impersonated. Can include domain name: DOMAIN\User.
        /// </summary>
        [Required]
        public string Username
        {
            get { return _username; }
            set { _username = value; }
        }

        /// <summary>
        /// Password of user to be impersonated.
        /// </summary>
        [Required]
        public string Password
        {
            get { return _password; }
            set { _password = value; }
        }


        /// <summary>
        /// Short username; without domain name.
        /// </summary>
        protected string ShortUsername
        {
            get
            {
                if (_username != null)
                {
                    int idx = _username.IndexOf('\\');
                    if (idx != -1)
                    {
                        return _username.Substring(idx + 1);
                    }
                    else
                        return _username;
                }
                else
                    return _username;
            }
        }

        /// <summary>
        /// Property getter for domain name. Extracted from Username.
        /// </summary>
        protected string Domain
        {
            get
            {
                if (_username != null)
                {
                    int idx = _username.IndexOf('\\');
                    if (idx != -1)
                    {
                        return _username.Substring(0, idx);
                    }
                    else
                        return null;
                }
                else
                    return null;
            }
        }

        /// <summary>
        /// Execute the command.
        /// </summary>
        /// <param name="pathToTool">Executable tool path</param>
        /// <param name="responseFileCommands">Response file commands</param>
        /// <param name="commandLineCommands">Command line args</param>
        /// <returns></returns>
        protected override int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands)
        {           
                ImpersonationHelper imp = new ImpersonationHelper();
                Log.LogMessage("Impersonating user '" + ShortUsername + "' on domain '" + Domain + "'");
                if (imp.ImpersonateValidUser(ShortUsername, Domain, Password))
                {
                    Log.LogMessage("Successfully impersonated.");
                    int retVal = base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands);
                    imp.UndoImpersonation();

                    return retVal;
                }
                else
                {
                    Log.LogError("Impersonation failed.");
                    return 1;
                }
        }
    }
}
